﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Steema.TeeChart;
using Steema.TeeChart.Styles;
using System.IO;
using System.Collections;

namespace FACUI.frmDialog
{
    public partial class frmChart : Form
    {
        //传感器分组编号
        private int iSerieStyle = -1;
        public frmChart(int Seriestyle= -1 )
        {
            iSerieStyle = Seriestyle;
            InitializeComponent();
            tChart2.AutoRepaint = false;
            tChart2.Series.Clear();
            this.AddSeries(tChart2, Color.YellowGreen);
            tChart2.Header.Text = "光谱图";
            tChart2.Axes.Bottom.Automatic = false;
            tChart2.Axes.Bottom.SetMinMax(1525, 1570);
            tChart2.Axes.Left.Automatic = false;
            tChart2.Axes.Left.SetMinMax(0,70000);
            tChart2.AutoRepaint = true;
            timer = new Timer();
            timer.Interval = 50;
            timer.Tick += new EventHandler(timer_Tick);
            timer.Enabled = true;
            tabControl1.SelectedIndex = 1;

            tChart1.AutoRepaint = false;
            tChart1.Series.Clear();
            this.AddSeries(tChart1, Color.YellowGreen);
            this.AddSeries(tChart1, Color.YellowGreen);
            tChart1.Axes.Bottom.Automatic = false;
            tChart1.Header.Text = string.Empty;
            tChart1.AutoRepaint = true;
            tChart1.Invalidate();
            this.hScrollBar1.Visible = false;
            tChart1.Axes.Left.Automatic = false;
            tChart1.Axes.Left.SetMinMax(-1,1);
            tChart1.Axes.Bottom.Automatic = true;
        }

        protected override void OnClosing(CancelEventArgs e)
        {
            if (timer != null)
            {
                timer.Enabled = false;
            }
            base.OnClosing(e);
        }

        private int iCount = 0; 
        void timer_Tick(object sender, EventArgs e)
        {
            try
            {
                //绘制光谱图
                if (tabControl1.SelectedIndex == 1)
                {
                    double[] _d = CSource.dSpectrum;
                    tChart2.AutoRepaint = false;
                    tChart2.Series[0].Clear();
                    int i = 0;
                    for (double dCur = 1525, pos = 45d / 256d; dCur < 1570; dCur += pos)
                    {
                        tChart2.Series[0].Add(dCur, _d[i++]);
                    }
                    tChart2.AutoRepaint = true;
                    tChart2.Invalidate();
                }
                //绘制波长图
                else
                {
                    CSource.mutqwavsrc.WaitOne();
                    if (CSource._queWavSource.Count == 0)
                    {
                        CSource.mutqwavsrc.ReleaseMutex();
                        return;
                    }
                    Queue<double[]> tmp= CSource._queWavSource.Dequeue();
                    CSource.mutqwavsrc.ReleaseMutex();
                    if (tmp == null)
                    {
                        return;
                    }
                    iCount = 0;
                    tChart1.AutoRepaint = false;
                    foreach (double[] dd in tmp)
                    {
                        if (dd.Length < 2) continue;
                        tChart1.Series[0].Add(dd[0] - Math.Truncate(dd[0]));
                        tChart1.Series[1].Add(dd[1] - Math.Truncate(dd[1]));
                        iCount++;
                    }
                    if (tChart1.Series[0].Count > 20000 && tChart1.Series[1].Count > 2000)
                    {
                        tChart1.Series[0].Delete(0, iCount-20000);
                        tChart1.Series[1].Delete(0, iCount-20000);
                    }
                    tChart1.AutoRepaint = true;
                    tChart1.Invalidate();

                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.StackTrace+":"+ex.Message);
            }
        }
        private void AddSeries(TChart tchart, Color lineColor)
        {
            FastLine fastline = new FastLine();
            fastline.Color = lineColor;
            tchart.Series.Add(fastline);
        }

        private Timer timer = null;
        private Timer tPlayBack = null;
        private long[] lIndex = null;
        private int iCurIndex = 0;
        private void radioCurrent_CheckedChanged(object sender, EventArgs e)
        {
            RadioButton radio = sender as RadioButton;
            if (radio.Name == "radioCurrent")
            {
                if (timer != null) timer.Enabled = true;
                this.hScrollBar1.Visible = false;
            }
            else
            {
                if (timer != null) timer.Enabled = false;
                this.hScrollBar1.Minimum = 0;
                CSource.mutqlong.WaitOne();
                if (CSource._Quelong.Count > 1)
                {
                    lIndex = CSource._Quelong.ToArray();
                    this.hScrollBar1.Minimum = 0;
                    this.hScrollBar1.Maximum = lIndex.Length - 1;
                    CSource.mutqlong.ReleaseMutex();
                    this.hScrollBar1.Value = this.hScrollBar1.Maximum;
                    this.hScrollBar1.Visible = true;
                    this.hScrollBar1.ValueChanged += new EventHandler(hScrollBar1_ValueChanged);
                    tPlayBack = new Timer();
                    tPlayBack.Interval = 80;
                    tPlayBack.Tick += new EventHandler(tPlayBack_Tick);
                    tPlayBack.Enabled = false;
                }
                else
                {
                    CSource.mutqlong.ReleaseMutex();
                }
            }
        }

        void tPlayBack_Tick(object sender, EventArgs e)
        {
            tPlayBack.Enabled = false;
            iCurIndex = hScrollBar1.Value;
            //开始结束位置调整
            int ioffset=0;
            //显示区间开始位置
            long lStartPosition = 0;
            //显示数据长度
            int iLen = 0;

            //开始位置
            int iStartPos=iCurIndex-5;
            //结束位置
            int iEndPos=iCurIndex+5;

            //记录时长大于10s
            if(iStartPos<0)
            {
                ioffset=Math.Abs(iStartPos);
                iStartPos = 0;
                iEndPos += ioffset;
                if (iEndPos > hScrollBar1.Maximum)
                {
                    iEndPos = hScrollBar1.Maximum;
                    hScrollBar1.Visible = false;
                }
            }
            else if(iEndPos>hScrollBar1.Maximum)
            {
                ioffset = iEndPos - hScrollBar1.Maximum;
                iEndPos = hScrollBar1.Maximum;
                iStartPos -= ioffset;
                if (iStartPos < 0)
                {
                    iStartPos = 0;
                    hScrollBar1.Visible = false;
                }
            }
            Queue<double[]> QueueWav = new Queue<double[]>(32 * 10 * 2000);
            /******************************读取解析后的文件******************************/
            if (CSource.IsAnalysizingFinished)
            {
                long[] lIndexArray = CSource.wavQIndex.ToArray();
                lStartPosition = lIndexArray[iStartPos];
                iLen = (int)((lIndexArray[iEndPos] - lIndexArray[iStartPos]) & (0xFFFFFFFF));
                if (!File.Exists(CSource.strTmpPath))
                {
                    tPlayBack.Enabled = true;
                    return;
                }
                FileStream _fswav = File.OpenRead(CSource.strTmpPath);
                BinaryReader _brwav = new BinaryReader(_fswav);
                _fswav.Seek(lStartPosition, SeekOrigin.Begin);
                byte[] bwavs = _brwav.ReadBytes(iLen);
                _fswav.Close();

                double[] dwav = new double[4];
                iLen = iLen / 32;
                for (int i = 0; i < iLen; i++)
                {
                    Array.Clear(dwav, 0, 4);
                    for (int n = 0; n < 4; n++)
                    {
                        dwav[n] = BitConverter.ToDouble(bwavs, 32 * i + 8 * n);
                    }
                    QueueWav.Enqueue((double[])dwav.Clone());
                }
            }
            /******************************解析光谱文件******************************/
            else
            {
                lStartPosition = lIndex[iStartPos];
                iLen = (int)((lIndex[iEndPos] - lIndex[iStartPos]) & (0xFFFFFFFF));
                if (!File.Exists(CSource.strCurPath))
                {
                    tPlayBack.Enabled = true;
                    return;
                }
                FileStream _ffss = File.OpenRead(CSource.strCurPath);
                BinaryReader _br = new BinaryReader(_ffss);
                _ffss.Seek(lStartPosition, SeekOrigin.Begin);
                byte[] bytes = _br.ReadBytes(iLen);
                _ffss.Close();
                //读出的数据计算波长绘到窗口
                iLen = iLen / 512;
                long lStartPos = lStartPosition / 512L;
                double[] _wavlen = new double[32];
                double[] _tmpData = new double[256];
                for (int i = 0; i < iLen; i++)
                {
                    Array.Clear(_tmpData, 0, 256);
                    Array.Clear(_wavlen, 0, _wavlen.Length);
                    for (int n = 0; n < 256; n++)
                    {
                        _tmpData[n] = double.Parse((BitConverter.ToUInt16(bytes, 512 * i + 2 * n)).ToString());
                    }
                    CSource.dSpectrum = _tmpData;
                    double dAvrg = _tmpData.Average() + 5000;
                    for (int j = 0; j < _tmpData.Length; j++)
                    {
                        if (_tmpData[j] <= dAvrg)
                        {
                            _tmpData[j] = 0;
                        }
                    }
                    CSource.GetWavesLength(_tmpData, ref _wavlen);
                    QueueWav.Enqueue((double[])_wavlen.Clone());
                }
            }
            tChart1.AutoRepaint = false;
            tChart1.Series[0].Clear();
            tChart1.Series[1].Clear();
            tChart1.Axes.Bottom.Automatic = false;
            tChart1.Axes.Bottom.SetMinMax(iStartPos, iStartPos + iLen);
            int iIndex = 0;
            foreach (double[] dd in QueueWav)
            {
                foreach (double d in dd)
                {
                    if (Math.Abs(d - 1532.5) < 1.5)
                    {
                        tChart1.Series[0].Add(iStartPos + iIndex++, d - 1532.5);
                    }
                    if (Math.Abs(d - 1540.6) < 1.5)
                    {
                        tChart1.Series[1].Add(iStartPos + iIndex++, d - 1540.6 + 0.5);
                    }
                }
            }
            tChart1.AutoRepaint = true;
            tChart1.Invalidate();

            //tChart2.AutoRepaint = false;
            //tChart2.Series[0].Clear();
            //int k = 0;
            //for (double dCur = 1525, pos = 45d / 256d; dCur < 1570; dCur += pos)
            //{
            //    tChart2.Series[0].Add(dCur, _tmpData[k++]);
            //}
            //tChart2.AutoRepaint = true;
            //tChart2.Invalidate();
        }

        void hScrollBar1_ValueChanged(object sender, EventArgs e)
        {
            if (tPlayBack != null)
            {
                tPlayBack.Enabled = true;
            }
        }

        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            msg = new Message();
            if (keyData == (Keys.Alt | Keys.End))
            {
                radioPlayBack.Checked = true;
                OpenFileDialog ofd = new OpenFileDialog();
                ofd.Filter = "记录文件（）*.dat|*.dat";
                if (DialogResult.OK == ofd.ShowDialog())
                {
                    string strInx = ofd.FileName.ToLower();
                    CSource.strCurPath = strInx;
                    CSource.strTmpPath = strInx.Replace(".dat", ".tmplx");
                    strInx = strInx.Replace(".dat",".inx");
                    byte[] bInx = null;
                    if (File.Exists(strInx))
                    {
                        bInx = File.ReadAllBytes(strInx);
                        if (bInx.Length < 80)
                        {
                            bInx = null;
                        }
                    }
                    if (bInx != null)
                    {
                        lIndex = new long[bInx.Length / 8];
                        for (int i = 0; i < lIndex.Length; i++)
                        {
                            lIndex[i] = BitConverter.ToInt64(bInx, 8 * i);
                        }
                    }
                    else
                    {
                        FileInfo fi = new FileInfo(CSource.strCurPath);
                        long lpack = fi.Length / 512L;
                        if (lpack / 2000L <= 0)
                        {
                            MessageBox.Show("打开文件太小！");
                            return base.ProcessCmdKey(ref msg, keyData);
                        }
                        lIndex = new long[lpack / 2000L+2];
                        lIndex[lIndex.Length - 1] = fi.Length - 512;
                        for (int i = 0; i < lIndex.Length-1; i++)
                        {
                            lIndex[i] = 512*2000*i;
                        }                        
                    }
                    System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(AnalysizingSource), null);
                    if (timer != null) timer.Enabled = false;
                    this.hScrollBar1.Minimum = 0;
                    this.hScrollBar1.Maximum = lIndex.Length-1;
                    this.hScrollBar1.Value = this.hScrollBar1.Maximum;
                    this.hScrollBar1.Visible = true;
                    this.hScrollBar1.ValueChanged += new EventHandler(hScrollBar1_ValueChanged);                    
                    tPlayBack = new Timer();
                    tPlayBack.Interval = 80;
                    tPlayBack.Tick += new EventHandler(tPlayBack_Tick);
                    tPlayBack.Enabled = true;
                }
            }
            return base.ProcessCmdKey(ref msg, keyData);
        }
        private void AnalysizingSource(object o)
        {
            try
            {
                CSource.IsAnalysizingFinished = false;

                if (File.Exists(CSource.strTmpPath))
                {
                    File.Delete(CSource.strTmpPath);
                }
                FileStream _fwav = File.Create(CSource.strTmpPath);
                BinaryWriter _wavbw = new BinaryWriter(_fwav, Encoding.Default);

                FileStream _ffss = File.OpenRead(CSource.strCurPath);
                BinaryReader _br = new BinaryReader(_ffss);

                double[] _wavlen = new double[32];
                double[] _tmpData = new double[256];
                CSource.wavQIndex.Enqueue(0L);
                for (int i = 1; i < lIndex.Length; i++)
                {
                    int iLen = (int)(((lIndex[i] - lIndex[i - 1]) / 512L) & (0xFFFFFFFF));
                    byte[] bytes = _br.ReadBytes((int)(lIndex[i] - lIndex[i - 1]));
                    for (int k = 0; k < iLen; k++)
                    {
                        Array.Clear(_tmpData, 0, 256);
                        Array.Clear(_wavlen, 0, _wavlen.Length);
                        for (int n = 0; n < 256; n++)
                        {
                            _tmpData[n] = double.Parse((BitConverter.ToUInt16(bytes, 512 * k + 2 * n)).ToString());
                        }
                        double dAvrg = _tmpData.Average() + 5000;
                        for (int j = 0; j < _tmpData.Length; j++)
                        {
                            if (_tmpData[j] <= dAvrg)
                            {
                                _tmpData[j] = 0;
                            }
                        }
                        CSource.GetWavesLength(_tmpData, ref _wavlen);
                        foreach (double d in _wavlen)
                        {
                            _wavbw.Write(BitConverter.GetBytes(d));
                        }
                    }
                    CSource.wavQIndex.Enqueue(_fwav.Position);
                }
                _ffss.Close();
                _fwav.Close();
                CSource.IsAnalysizingFinished = true;
            }
            catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.StackTrace+":"+ex.Message); }
        }
    }
}
